package com.ibeeking.found.upms.b.rest.service.impl;

import com.ibeeking.found.upms.b.rest.service.IOpenUrlRelationService;
import com.ibeeking.found.upms.b.rest.service.IOpenUrlService;
import com.ibeeking.found.common.base.BaseDO;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.upms.service.common.bo.OpenUrlBO;
import com.ibeeking.found.upms.service.common.dos.OpenUrlDO;
import com.ibeeking.found.upms.service.common.param.OpenUrlParam;
import com.ibeeking.found.upms.service.common.query.OpenUrlPageQuery;
import com.ibeeking.found.upms.service.common.vo.OpenUrlPageVO;
import com.ibeeking.found.upms.service.common.vo.OpenUrlVO;
import com.ibeeking.found.upms.service.mapper.OpenUrlMapper;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @ClassName OpenUrlServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-03-31 16:56
 **/
@Service
public class OpenUrlServiceImpl implements IOpenUrlService {

    @Resource
    private OpenUrlMapper openUrlMapper;
    @Resource
    private IOpenUrlRelationService openUrlRelationServiceImpl;

    @Override
    public Page<OpenUrlPageVO> pageList(OpenUrlPageQuery query) {
        LambdaQueryWrapper<OpenUrlDO> queryWrapper = new LambdaQueryWrapper<>(OpenUrlDO.class)
                .orderByAsc(OpenUrlDO::getSort)
                .orderByDesc(BaseDO::getCreateTime)
                .eq(null != query.getPublishStatus(), OpenUrlDO::getPublishStatus, query.getPublishStatus())
                .likeRight(StringUtils.isNotBlank(query.getUrl()), OpenUrlDO::getUrl, query.getUrl())
                .like(StringUtils.isNotBlank(query.getName()), OpenUrlDO::getName, query.getName());
        Page<OpenUrlDO> page = openUrlMapper.selectPage(new Page<>(query.getPageNum(), query.getPageSize()), queryWrapper);
        return BeanUtil.convertPage(page, OpenUrlPageVO.class);
    }

    @Override
    public Boolean add(OpenUrlParam param) {
        OpenUrlDO openUrlDO = BeanUtil.convertBean(param, OpenUrlDO.class);
        openUrlDO.setCreateBy(UserUtils.getUserId());
        openUrlDO.setCreateTime(LocalDateTime.now());
        openUrlDO.setModifyTime(LocalDateTime.now());
        if (!openUrlDO.getUrl().startsWith("/")) {
            openUrlDO.setUrl("/".concat(openUrlDO.getUrl()));
        }
        if (!checkUnique(openUrlDO)) {
            throw new BusinessException("当前路径已存在,请不要重复配置");
        }
        return openUrlMapper.insert(openUrlDO) > 0;
    }

    @Override
    public Boolean modify(OpenUrlParam param) {
        OpenUrlBO openUrlBO = getBean().queryById(param.getId());
        if (PublishStatusEnum.ENABLE.getValue().equals(openUrlBO.getPublishStatus())) {
            throw new BusinessException("请先禁用后再修改");
        }
        OpenUrlDO openUrlDO = BeanUtil.convertBean(param, OpenUrlDO.class);
        openUrlDO.setModifyBy(UserUtils.getUserId());
        openUrlDO.setModifyTime(LocalDateTime.now());
        if (!openUrlDO.getUrl().startsWith("/")) {
            openUrlDO.setUrl("/".concat(openUrlDO.getUrl()));
        }
        if (!checkUnique(openUrlDO)) {
            throw new BusinessException("当前路径已存在,请不要重复配置");
        }
        return openUrlMapper.updateById(openUrlDO) > 0;
    }

    @Override
    public OpenUrlVO view(Long id) {
        return BeanUtil.convertBean(getBean().queryById(id), OpenUrlVO.class);
    }

    @Override
    public OpenUrlBO queryById(Long id) {
        OpenUrlDO openUrlDO = openUrlMapper.selectById(id);
        return BeanUtil.convertBean(openUrlDO, OpenUrlBO.class);
    }

    @Override
    public Boolean changeStatus(Long id, Integer status) {
        OpenUrlDO openUrlDO = new OpenUrlDO();
        openUrlDO.setId(id);
        openUrlDO.setPublishStatus(status);
        openUrlDO.setModifyBy(UserUtils.getUserId());
        openUrlDO.setModifyTime(LocalDateTime.now());
        return openUrlMapper.updateById(openUrlDO) > 0;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean del(Long id) {
        OpenUrlBO openUrlBO = getBean().queryById(id);
        if (PublishStatusEnum.ENABLE.getValue().equals(openUrlBO.getPublishStatus())) {
            throw new BusinessException("请先禁用后再删除");
        }
        openUrlMapper.deleteById(id);
        openUrlRelationServiceImpl.delByUrlId(id);
        return true;
    }

    @Override
    public List<OpenUrlBO> queryByIds(List<Long> ids) {
        List<OpenUrlDO> openUrlDos = openUrlMapper.selectBatchIds(ids);
        return JsonUtils.jsonToList(openUrlDos, OpenUrlBO.class);
    }

    private static IOpenUrlService getBean() {
        return SpringBeanUtil.getBean(IOpenUrlService.class);
    }

    private Boolean checkUnique(OpenUrlDO openUrlDO) {
        Integer count = openUrlMapper.selectCount(new LambdaQueryWrapper<>(OpenUrlDO.class)
                .ne(null != openUrlDO.getId(), OpenUrlDO::getId, openUrlDO.getId())
                .and(
                        Wrapper -> Wrapper
                                .eq(StringUtils.isNotBlank(openUrlDO.getUrl()), OpenUrlDO::getUrl, openUrlDO.getUrl())
                )
        );
        return 0 == count;
    }
}
